use axum::extract::State;
/// sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/introduction/sea-orm
/// 使用 sea-orm-cli 生成实体， 官方文档： https://crates.io/crates/sea-orm-cli
/*
SeaORM 概念
在 SeaORM 中，具有一组表的数据库称为 Schema。
每个表对应于 SeaORM 中的一个 Entity 实体，它可以帮助您对相关表执行CRUD（创建、读取、更新和删除）操作。
Entity 特性提供了一个API，用于在运行时检查其属性（Column、Relation和PrimaryKey）。
每个表都有多个列，称为属性。
这些属性及其值被分组到Rust结构（ Model 数据模型）中，以便您可以对其进行操作。
但是，Model 仅用于读取操作。要执行插入、更新或删除，您需要使用 ActiveModel，它在每个属性上附加元数据。
最后，SeaORM 中没有单例（全局上下文）。应用程序代码负责管理DatabaseConnection的所有权。我们确实提供了包括Rocket、Actix、axum和诗意在内的web框架的集成示例，以帮助您快速入门。
*/

use chrono::NaiveDateTime;
use sea_orm::{Condition, Database, DatabaseBackend, DbBackend, ExecResult, IntoActiveModel, JoinType, NotSet, QueryOrder, QuerySelect, QueryTrait, Schema, Statement};
use sea_orm::ActiveValue::Set;
use sea_orm::entity::prelude::*;
use sea_orm::sea_query::{Alias, ForeignKey, MysqlQueryBuilder, Query, Table};
use sea_orm::sea_query::ArrayType::Char;
use crate::{blog, blog::Entity as Blog};

/// 1、定义 User 数据模型, 它包含了所有列的字段，用于存储查询结果的 Rust 结构体
/// 下面的数据模型 Model 的一切配置参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/generate-entity/entity-structure
/*
数据模型是代表数据库表中的行的结构体。它包含了所有列的字段，并且通常包含一些元数据，比如是否为主键等
Model 用于存储查询结果的 Rust 结构体
DeriveEntityModel 宏完成了定义实体与关联模型、列和主键的所有繁重工作。
数据模型(Model)  数据模型是代表数据库表中的行的结构体。它包含了所有列的字段，并且通常包含一些元数据，比如是否为主键等。
*/
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "t_user")]
pub struct Model {
    // primary_key 表示该字段为主键
    #[sea_orm(primary_key, auto_increment = false)]
    // #[serde(skip_deserializing)]
    pub user_id: String,
    pub name: String,
    pub password: String,
    pub age: u32,
    pub email: String,
    #[sea_orm(column_type = "Double")]
    pub score: f64,
    // 如果要忽略特定的模型属性，使其不映射到数据库列，可以使用 ignore 注释。被标注的字段不参与表的映射，也不会被序列化。
    #[sea_orm(ignore)]
    pub gender: bool,
    pub price: Decimal,
    // unique 和 indexed 表示该字段为唯一索引，即字段值必须唯一。nullable 表示该字段可以为空。标注在 Option<T> 类型上时，表示该字段可以为空。
    #[sea_orm(column_type = "Text", default_value = "Sam", unique, indexed, nullable)]
    pub description: Option<String>,
    #[sea_orm(column_type = "DateTime", nullable)]
    pub create_time: Option<NaiveDateTime>,
    #[sea_orm(column_type = "DateTime", nullable)]
    pub update_time: Option<NaiveDateTime>,
}

/// 2、Relation（关系）
/// 一个用户可以有多个博客，但是每个博客只能有一个作者，所以用户和博客之间属于一对多的关系。
/// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/relation/one-to-many
/*
关系(Relation)     关系用于定义实体之间的关联，比如一对多、多对多或者一对一的关系。这有助于在查询时获取相关联的数据。
Relation 用于描述实体之间的关系，比如一对一、一对多、多对一、多对多等。
它是通过在模型中使用关联宏（`sea_orm::belongs_to`、`sea_orm::has_one`、`sea_orm::has_many`等）来定义实体之间的关系。
Relation主要用于在查询时构建JOIN语句，以便在一次查询中获取关联实体的数据。
*/
/// DeriveRelation 是必须要加的，不能省略。它会生成一个枚举 Relation，用于描述实体之间的关系。
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    // 一对多关系，一个用户有多个博客，还存在一对一关系，使用 #[sea_orm(has_one = "super::blog::Entity")]
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/relation/one-to-one
    #[sea_orm(has_many = "super::blog::Entity")]
    Blog,
}

/// 3、Related（关联）
/*
Related 是指在已经获取到一个实体的情况下，通过 Related trait 来获取其关联实体的数据。
Related trait提供了一系列方法（如`related`, `related_with`等）用于查询关联实体的数据。
通过Related，你可以方便地在已有实体的基础上，获取与之相关联的其他实体的数据，而无需重新构建查询。
*/
impl Related<blog::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Blog.def()
    }
}

/// Related 是指在已经获取到一个实体的情况下，通过 Related trait 来获取其关联实体的数据
// SeaORM 中的 Relation 关系是一个箭头：它有 from 和 to 两个方向。user_menu::Relation::User 定义了 UserMenu->User。调用 rev 会将其反转为 User->UserMenu。
impl Related<super::menu::Entity> for Entity {
    // 最终的关系是 User -> UserMenu -> Menu
    fn to() -> RelationDef {
        super::user_menu::Relation::Menu.def()
    }

    fn via() -> Option<RelationDef> {
        // 原始的关系是 UserMenu -> User,
        // 调用 `rev` 之后，关系变为 User -> UserMenu
        Some(super::user_menu::Relation::User.def().rev())
    }
}


/// 4、活动模型(ActiveModel)  和  活动模型行为(ActiveModelBehavior)
/*
活动模型(ActiveModel)    活动模型是用于创建、更新和删除实体的结构体。它与数据模型非常相似，但允许字段被标记为Set或NotSet，这使得你可以只更新某些字段，而不是整个实体。
ActiveModel 具有其相应 Model 的所有属性，但所有属性都包含在 ActiveValue 中。即在 Model 字段的基础上，使用 ActiveValue 进行封装，以便在数据库中进行更新。例如： pub id: ActiveValue<i32>
活动模型行为(ActiveModelBehavior)  活动模型行为是一些可以附加到活动模型上的功能，比如自动填充时间戳。
活动模型是用于创建、更新和删除实体的结构体。它与数据模型非常相似，但允许字段被标记为`Set`或`NotSet`，这使得你可以只更新某些字段，而不是整个实体。不改变数据的原有内容，查询操作直接使用数据模型
活动模型行为是用于自定义活动模型的行为的 trait。它包含了一些方法，如`before_save`、`after_save`、`before_delete`、`after_delete`、自动填充时间戳等，用于在保存或删除实体之前或之后执行一些操作。
*/
impl ActiveModelBehavior for ActiveModel {
    // 使用默认值创建一个新的 ActiveModel。也由 `Default::default()` 使用。
    fn new() -> Self {
        Self {
            user_id: Set(Uuid::new_v4().to_string()),
            ..ActiveModelTrait::default()
        }
    }

    // 插入/更新前会触发
    async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
    where
        C: ConnectionTrait,
    {
        if self.price.as_ref() <= &NotSet {
            Err(DbErr::Custom(format!(
                "[before_save] Invalid Price, insert: {}",
                insert
            )))
        } else {
            Ok(self)
        }
    }

    // 插入/更新后会触发
    async fn after_save<C>(model: Model, db: &C, insert: bool) -> Result<Model, DbErr>
    where
        C: ConnectionTrait,
    {
        Ok(model)
    }

    // 删除前会触发
    async fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>
    where
        C: ConnectionTrait,
    {
        Ok(self)
    }

    // 删除后会触发
    async fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>
    where
        C: ConnectionTrait,
    {
        Ok(self)
    }
}
// 不要删除关系枚举（Relation）或活动模型行为（ActiveModelBehavior） impl 块，即使它们是空的。
// 该提示的来源为 sea-orm 官方网站，https://www.sea-ql.org/SeaORM/docs/generate-entity/entity-structure



// 除了查询操作，其他所有操作都可以用活动模型 ActiveModel 来完成。数据模型 Model 仅用于查询。
// 实体 Entity 用于管理数据模型 Model 和活动模型 ActiveModel。并提供了一系列方法用于查询、插入、更新和删除数据。
// 以下的 Entity 都代表当前的文件中的数据库操作对象，类似 Java 中的 DAO 对象
async fn user_database_demo() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

}


/// 以下是对用户表的增删改查操作
// 1、Select 查询操作
async fn user_select() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 1、Select 查询操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/select
    // 查找所有 models ，相当于 SELECT * FROM `t_user`
    let users: Vec<Model> = Entity::find().all(&db).await?;
    // 相当于 SELECT "t_blog"."blog_id", "t_blog"."title", "t_blog"."user_id" FROM "t_blog" WHERE "t_blog"."user_id" IN (..)
    let blogs: Vec<Vec<blog::Model>> = users.load_many(Blog, &db).await?;
    // 遍历查询结果
    for (user, blogs) in users.into_iter().zip(blogs.into_iter()) { .. }

    // 查找和筛选 name 匹配的 models
    let users: Vec<Model> = Entity::find()
        .filter(Column::Name.contains("chocolate"))
        // 排序，asc 升序，desc 降序
        .order_by_asc(Column::Name)
        // 分页，每页 10 条
        .paginate(&db, 10)
        .await?;

    // 查找一个模型，find_by_id 方法接受一个主键值作为参数，类型需要和主键类型一致
    let user: Option<Model> = Entity::find_by_id(10.to_string()).one(&db).await?;

    if let Some(user) = user {
        // 查找关联模型，比如用户的博客 (lazy)
        let blogs: Vec<blog::Model> = user.find_related(Blog).all(&db).await?;
    } else {
        // 处理没有找到的情况
        println!("User not found");
    }

    // 查找关联模型，比如用户的博客 (eager)
    // 加载关联模型，比如加载用户的博客
    let user_with_blogs: Vec<(Model, Vec<blog::Model>)> =
        Entity::find().find_with_related(Blog).all(&db).await?;
    // 加载关联模型，比如加载用户的博客，从上面的结果中加载博客数据,
    let blogs: Vec<Vec<blog::Model>> = user_with_blogs.load_many(Blog, &db).await?;


    // 光标分页
    // 创建一个按“用户”排序的光标 user_id 相当于创建了一个基于指定字段的分页器
    let mut cursor = Entity::find().cursor_by(Column::UserId);

    // 按“用户”筛选分页结果`user_id'>1和`user_id `<100
    cursor.after(1).before(100);

    // 获取前10行（按“蛋糕”、“id”ASC排序）
    for user in cursor.first(10).all(&db).await? {
        // 在用户上做点什么 user: user::Model
    }

    //获取最后10行（按'cake'.'id'DESC排序，但行是按升序返回的）
    for user in cursor.last(10).all(&db).await? {
        // 在用户上做点什么 user: user::Model
    }

    // 仅选择 name 名称列
    assert_eq!(
        Entity::find()
            .select_only()
            .column(Column::Name)
            .build(DbBackend::MySql)
            .to_string(),
        r#"SELECT "cake"."name" FROM "cake""#
    );

    // 选择多个列
    assert_eq!(
        Entity::find()
            .select_only()
            .columns([Column::UserId, Column::Name])
            .build(DbBackend::MySql)
            .to_string(),
        r#"SELECT "cake"."id", "cake"."name" FROM "cake""#
    );

    // 选择列并取别名
    assert_eq!(
        Entity::find()
            .column_as(Expr::col(Column::UserId).max().sub(Expr::col(Column::UserId)), "id_diff")
            .column_as(Expr::cust("CURRENT_TIMESTAMP"), "current_time")
            .build(DbBackend::Postgres)
            .to_string(),
        r#"SELECT "cake"."id", "cake"."name", MAX("id") - "id" AS "id_diff", CURRENT_TIMESTAMP AS "current_time" FROM "cake""#
    );


    let res: Vec<(String, i64)> = Entity::find()
        .select_only()
        .column(Column::Name)
        .group_by(Column::Name)
        // 数据结果转换为元组，还可以是其他类型
        .into_tuple()
        .all(&db)
        .await?;
}

// 2、Insert 插入操作
async fn user_insert() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 2、Insert 插入操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/insert
    let user = ActiveModel {
        name: Set("Apple Pie".to_owned()),
        ..Default::default()
    };
    let insert_result = Entity::insert(user).exec(&db).await?;


    let blog = blog::ActiveModel {
        title: Set("Apple".to_owned()),
        ..Default::default() // no need to set primary key
    };

    let post = blog::ActiveModel {
        title: Set("Pear".to_owned()),
        ..Default::default()
    };

    // 插入一条数据
    let post = post.insert(&db).await?;
    let post: blog::ActiveModel = post.into_active_model();

    // 插入多条数据
    Blog::insert_many([blog, post]).exec(&db).await?;


    /// 3、Update 更新操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/update
    // 根据 id 查找博客
    let blog: Option<blog::Model> = Blog::find_by_id(1).one(&db).await?;
    let mut blog: blog::ActiveModel = blog.unwrap().into();

    // 设置修改的字段
    blog.title = Set("Sweet pear".to_owned());

    // 单个更新
    let pear: blog::Model = blog.update(&db).await?;

    // 更新多个: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'
    Blog::update_many()
        .col_expr(blog::Column::BlogId, Expr::value(Value::Int(None)))
        // filter 方法用于添加 WHERE 查询条件
        .filter(blog::Column::Title.contains("Apple"))
        .exec(&db)
        .await?;
}

// 3、Update 更新操作
async fn user_update() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 3、Update 更新操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/update
    // 根据 id 查找博客
    let blog: Option<blog::Model> = Blog::find_by_id(1).one(&db).await?;
    let mut blog: blog::ActiveModel = blog.unwrap().into();

    // 设置修改的字段
    blog.title = Set("Sweet pear".to_owned());

    // 单个更新
    let pear: blog::Model = blog.update(&db).await?;

    // 更新多个: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'
    Blog::update_many()
        .col_expr(blog::Column::BlogId, Expr::value(Value::Int(None)))
        // filter 方法用于添加 WHERE 查询条件
        .filter(blog::Column::Title.contains("Apple"))
        .exec(&db)
        .await?;
}

// 4、Save 保存操作
async fn user_save() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 4、Save 保存操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/sav
    // 构造一个新的博客
    let blog = blog::ActiveModel {
        blog_id: NotSet,
        title: Set("Banana".to_owned()),
        ..Default::default()
    };

    // 创建一个博客, 因为主键 primary key `id` is `NotSet` 没有设置，所以会自动生成一个 id
    let mut blog = blog.save(&db).await?;

    blog.title = Set("Banana Mongo".to_owned());

    // 更新一个博客, 因为主键 primary key `id` is `Set` 已经设置，所以会更新该 id 的数据
    let banana = blog.save(&db).await?;
}

// 5. Delete 删除操作
async fn user_delete() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 5、Delete 删除操作
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/delete
    // 删除一条数据
    let user: Option<Model> = Entity::find_by_id(1.to_string()).one(&db).await?;
    let user: Model = user.unwrap();
    // 数据模型 Model 仅用于查询，不能直接删除，需要用活动模型 ActiveModel 进行删除操作
    Entity::delete(user.into_active_model())
        .exec(&db)
        .await?;

    // 上面的简化版本
    let user: Option<Model> = Entity::find_by_id(1.to_string()).one(&db).await?;
    let user: Model = user.unwrap();
    user.delete(&db).await?;

    // 删除多个数据: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange'
    Entity::delete_many()
        // 此处的 contains 方法用于模糊匹配，等价于 LIKE '%Orange%'
        .filter(Column::Name.contains("Orange"))
        .exec(&db)
        .await?;
}

// 6、将查询的结果转换为 JSON 格式
async fn user_json() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 6、将查询的结果转换为 JSON 格式
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/json
    let users: Vec<serde_json::Value> = Entity::find()
        // filter 方法用于添加 WHERE 查询条件
        .filter(Column::Name.contains("chocolate"))
        .order_by_asc(Column::Name)
        // 转换为 JSON 格式
        .into_json()
        .paginate(&db, 50)
        .await?;
}

// 7、执行原始SQL
async fn user_raw_sql() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 7、原始SQL
    /// 参考 sea-orm 官方网站： https://www.sea-ql.org/SeaORM/docs/basic-crud/raw-sql
    let users: Option<Model> = Entity::find()
        .from_raw_sql(Statement::from_sql_and_values(
            DbBackend::MySql,
            r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE "id" = $1"#,
            [1.into()],
        ))
        .one(&db)
        .await?;


    // 获取原始SQL查询语句
    // 在任何CRUD操作上使用 build 和 to_string 方法来获取特定于数据库的原始SQL，以便进行调试。
    // 相当于 SELECT * FROM "t_user" WHERE "user_id" = 6
    let  stat = Entity::find_by_id(6.to_string())
        .build(DatabaseBackend::MySql)
        .to_string();
    println!("Raw SQL: {}", stat);

    // 执行原始SQL查询
    let query_res: Option<QueryResult> = db
        .query_one(Statement::from_string(
            DatabaseBackend::MySql,
            "SELECT * FROM `cake`;",
        ))
        .await?;
    let query_res = query_res.unwrap();
    let id: i32 = query_res.try_get("", "id")?;

    // 执行原始SQL语句
    let exec_res: ExecResult = db
        .execute(Statement::from_string(
            DatabaseBackend::MySql,
            "DROP DATABASE IF EXISTS `sea`;",
        ))
        .await?;
    assert_eq!(exec_res.rows_affected(), 1);
}

// 9、join 连接查询
async fn user_join() {
    let db = Database::connect("mysql://root:123456@localhost:3306/test").await.unwrap();

    /// 9、自定义 join 条件的关联查询
    /// 参考 sea-orm 官方网站：  https://www.sea-ql.org/SeaORM/docs/relation/custom-join-condition

    assert_eq!(
        Entity::find()
            .join(JoinType::LeftJoin, Relation::Blog.def())
            .build(DbBackend::MySql)
            .to_string(),
        [
            "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
            "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'",
        ]
            .join(" ")
    );
}

// 10、条件表达式，用于构造复杂的查询条件
async fn conditional_expressions() {
    /// 参考 sea-orm 官方网站：  https://www.sea-ql.org/SeaORM/docs/advanced-query/conditional-expression

    /// 1、and 条件
    // Condition::all() 用于构造 AND 条件表达式，Condition::any() 用于构造 OR 条件表达式。
    // 使用 Condition::all 方法构造AND条件表达式，并使用 add 方法附加 sea_query::SimpleExpr 中表示的任何条件。
    assert_eq!(
        Entity::find()
            .filter(
                Condition::all()
                    .add(Column::UserId.gte(1))
                    .add(Column::Name.like("%Cheese%"))
            )
            .build(DbBackend::MySql)
            .to_string(),
        [
            "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
            "WHERE `cake`.`id` >= 1 AND `cake`.`name` LIKE '%Cheese%'",
        ].join(" ")
    );

    /// 2、or 条件
    // 使用 Condition::any 方法构造OR条件表达式，并使用 add 方法附加 sea_query::SimpleExpr 中表示的任何条件。
    assert_eq!(
        Entity::find()
            .filter(
                Condition::any()
                    .add(Column::UserId.eq(4))
                    .add(Column::UserId.eq(5))
            )
            .build(DbBackend::MySql)
            .to_string(),
        [
            "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
            "WHERE `cake`.`id` = 4 OR `cake`.`id` = 5",
        ].join(" ")
    );


    /// 3、嵌套条件
    // add 方法还可以接受另一个条件表达式。通过这样做，我们可以灵活地构造复杂的嵌套条件。
    assert_eq!(
        Entity::find()
            // filter 方法用于添加 WHERE 查询条件
            .filter(
                Condition::all()
                    .add(
                        Condition::all()
                            .not()
                            .add(Expr::val(1).eq(1))
                            .add(Expr::val(2).eq(2))
                    )
                    .add(
                        Condition::any()
                            .add(Expr::val(3).eq(3))
                            .add(Expr::val(4).eq(4))
                    )
            )
            .build(DbBackend::MySql)
            .to_string(),
        r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE (NOT (1 = 1 AND 2 = 2)) AND (3 = 3 OR 4 = 4)"#
    );

}

// 11、聚合函数,用于对查询结果进行聚合操作.例如, 计算总数, 计算总和, 计算平均值等.
async fn aggregate_functions() {
    // 分组聚合
    assert_eq!(
        Entity::find()
            .select_only()
            .column(Column::Name)
            .group_by(Column::Name)
            .build(DbBackend::MySql)
            .to_string(),
        r#"SELECT "cake"."name" FROM "cake" GROUP BY "cake"."name""#
    );
    assert_eq!(
        Entity::find()
            .select_only()
            .column_as(Column::Age.count(), "count")
            .column_as(Column::Age.sum(), "sum_of_age")
            .group_by(Column::Name)
            .build(DbBackend::MySql)
            .to_string(),
        r#"SELECT COUNT("cake"."id") AS "count", SUM("cake"."id") AS "sum_of_id" FROM "cake" GROUP BY "cake"."name""#
    );

    // 过滤聚合
    // HAVING 子句用于过滤分组后的数据。它通常与 GROUP BY 语句一起使用，用来指定分组后的聚合数据需要满足的条件
    assert_eq!(
        Entity::find()
            .select_only()
            // 计算总数据量
            .column_as(Column::Age.count(), "count")
            // 计算总和
            .column_as(Column::Age.sum(), "sum_of_id")
            // 计算最大值
            .column_as(Column::Age.max(), "max_age")
            .group_by(Column::Name)
            .having(Expr::col(Alias::new("count")).gt(6))
            .build(DbBackend::MySql)
            .to_string(),
        "SELECT COUNT(`cake`.`id`) AS `count`, SUM(`cake`.`id`) AS `sum_of_id` FROM `cake` GROUP BY `cake`.`name` HAVING `count` > 6"
    );
}

// 12、于查询
async fn subquery() {
    assert_eq!(
        Entity::find()
            .filter(
                Condition::any().add(
                    Column::UserId.in_subquery(
                        Query::select()
                            .expr(Column::UserId.max())
                            .from(Entity)
                            .to_owned()
                    )
                )
            )
            .build(DbBackend::MySql)
            .to_string(),
        [
            "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
            "WHERE `cake`.`id` IN (SELECT MAX(`cake`.`id`) FROM `cake`)",
        ]
            .join(" ")
    );
}


// /// sea-orm 官方文档： https://docs.rs/sea-query/latest/sea_query/table/struct.TableCreateStatement.html
// // 通过 sea-orm 代码生成器创建表
// fn create_table(State(state): State<AppState>) -> Result<(), DbErr> {
//     // 使用 state.db 或 state.config
//     let db = state.db;
//
//     let table = Table::create()
//         .table(UserTable::Table)
//         .if_not_exists()
//         .comment("table's comment")
//         .col(ColumnDef::new(UserTable::Id).integer().not_null().auto_increment().primary_key())
//         .col(ColumnDef::new(Char::FontSize).integer().not_null().comment("font's size"))
//         .col(ColumnDef::new(Char::Character).string().not_null())
//         .col(ColumnDef::new(Char::SizeW).integer().not_null())
//         .col(ColumnDef::new(Char::SizeH).integer().not_null())
//         .col(ColumnDef::new(Char::FontId).integer().default(Value::Int(None)))
//         .foreign_key(
//             ForeignKey::create()
//                 .name("FK_2e303c3a712662f1fc2a4d0aad6")
//                 .from(Char::Table, Char::FontId)
//                 .to(Font::Table, Font::Id)
//                 .on_delete(ForeignKeyAction::Cascade)
//                 .on_update(ForeignKeyAction::Cascade)
//         )
//         .to_owned();
//
//     assert_eq!(
//         table.to_string(MysqlQueryBuilder),
//         [
//             r#"CREATE TABLE IF NOT EXISTS `character` ("#,
//             r#"`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,"#,
//             r#"`font_size` int NOT NULL COMMENT 'font\'s size',"#,
//             r#"`character` varchar(255) NOT NULL,"#,
//             r#"`size_w` int NOT NULL,"#,
//             r#"`size_h` int NOT NULL,"#,
//             r#"`font_id` int DEFAULT NULL,"#,
//             r#"CONSTRAINT `FK_2e303c3a712662f1fc2a4d0aad6`"#,
//             r#"FOREIGN KEY (`font_id`) REFERENCES `font` (`id`)"#,
//             r#"ON DELETE CASCADE ON UPDATE CASCADE"#,
//             r#") COMMENT 'table\'s comment'"#,
//         ].join(" ")
//     );
// }
//
//
// /// sea-orm 官方文档： https://www.sea-ql.org/SeaORM/docs/schema-statement/create-table
// // 通过原生 SQL 语句创建表
// fn create_table_mysql() {
//     let db_mysql = DbBackend::MySql;
//     let schema = Schema::new(db_mysql);
//
//     assert_eq!(
//         db_mysql.build(&schema.create_table_from_entity(CakeFillingPrice)),
//         Statement::from_string(
//             db_mysql,
//             [
//                 "CREATE TABLE `cake_filling_price` (",
//                 "`cake_id` int NOT NULL,",
//                 "`filling_id` int NOT NULL,",
//                 "`price` decimal NOT NULL,",
//                 "PRIMARY KEY `pk-cake_filling_price` (`cake_id`, `filling_id`),",
//                 "CONSTRAINT `fk-cake_filling_price-cake_id-filling_id` FOREIGN KEY (`cake_id`, `filling_id`) REFERENCES `cake_filling` (`cake_id`, `filling_id`)",
//                 ")",
//             ]
//                 .join(" ")
//         )
//     );
// }